package server;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import client.MapleClient;
import java.util.concurrent.locks.ReentrantLock;

public class AutobanManager implements Runnable {

    private static class ExpirationEntry implements Comparable<ExpirationEntry> {

        public long time;
        public int acc;
        public int points;

        public ExpirationEntry(long time, int acc, int points) {
            this.time = time;
            this.acc = acc;
            this.points = points;
        }

        @Override
        public int compareTo(AutobanManager.ExpirationEntry o) {
            return (int) (time - o.time);
        }

        @Override
        public boolean equals(Object oth) {
            if (!(oth instanceof AutobanManager.ExpirationEntry)) {
                return false;
            }
            final AutobanManager.ExpirationEntry ee = (AutobanManager.ExpirationEntry) oth;
            return (time == ee.time && points == ee.points && acc == ee.acc);
        }
    }

    private final Map<Integer, Integer> points = new HashMap<>();
    private final Map<Integer, List<String>> reasons = new HashMap<>();
    private final Set<ExpirationEntry> expirations = new TreeSet<>();
    private static final int AUTOBAN_POINTS = 5000; // change this if pop
    private static final AutobanManager instance = new AutobanManager();
    private final ReentrantLock lock = new ReentrantLock(true);

    public static final AutobanManager getInstance() {
        return instance;
    }

    public final void autoban(final MapleClient c, final String reason) {
        /*
         * if (c.getPlayer() == null) { return; } if (c.getPlayer().isGM() ||
         * c.getPlayer().isClone()) { c.getPlayer().dropMessage(5,
         * "[WARNING] A/b triggled : " + reason); return; } addPoints(c, AUTOBAN_POINTS,
         * 0, reason);
         */
    }

    public final void addPoints(final MapleClient c, final int points, final long expiration, final String reason) {
        /*
         * lock.lock(); try { List<String> reasonList; final int acc =
         * c.getPlayer().getAccountID();
         * 
         * if (this.points.containsKey(acc)) { final int SavedPoints =
         * this.points.get(acc); if (SavedPoints >= AUTOBAN_POINTS) { // Already auto
         * ban'd. return; } this.points.put(acc, SavedPoints + points); // Add
         * reasonList = this.reasons.get(acc); reasonList.add(reason); } else {
         * this.points.put(acc, points); reasonList = new LinkedList<String>();
         * reasonList.add(reason); this.reasons.put(acc, reasonList); }
         * 
         * if (this.points.get(acc) >= AUTOBAN_POINTS) { // See if it's sufficient to
         * auto ban if (c.getPlayer().isGM() || c.getPlayer().isClone()) {
         * c.getPlayer().dropMessage(5, "[WARNING] A/b triggled : " + reason); return; }
         * final StringBuilder sb = new StringBuilder("a/b ");
         * sb.append(c.getPlayer().getName()); sb.append(" (IP ");
         * sb.append(c.getSession().getRemoteAddress().toString()); sb.append("): ");
         * for (final String s : reasons.get(acc)) { sb.append(s); sb.append(", "); }
         * World.Broadcast.broadcastMessage(CWvsContext.serverNotice(0, "[Autoban] " +
         * c.getPlayer().getName() + " banned by the system (Last reason: " + reason +
         * ")")); // Calendar cal = Calendar.getInstance(); // cal.add(Calendar.DATE,
         * 60); // c.getPlayer().tempban(sb.toString(), cal, 1, false);
         * c.getPlayer().ban(sb.toString(), false, true, false); c.disconnect(true,
         * false); } else { if (expiration > 0) { expirations.add(new
         * ExpirationEntry(System.currentTimeMillis() + expiration, acc, points)); } } }
         * finally { lock.unlock(); }
         */
    }

    @Override
    public final void run() {
        final long now = System.currentTimeMillis();
        for (final ExpirationEntry e : expirations) {
            if (e.time <= now) {
                this.points.put(e.acc, this.points.get(e.acc) - e.points);
            } else {
                return;
            }
        }
    }
}
